﻿using HelperFromTheSkeleton.Convert;
using HelperFromTheSkeleton.Enums;
using HelperFromTheSkeleton.Model.DomainModels;
using HelperFromTheSkeleton.Model.PageModel;
using Microsoft.EntityFrameworkCore;
using System.Linq;
using System.Linq.Expressions;

namespace HelperFromTheSkeleton.EFBaseRepository
{
    /// <summary>
    /// 基础实现
    /// </summary>
    public class EFBaseRepositoryImpl<T> where T : BaseDomain
    {
        private readonly DbContext _hospitalWeChatPayDBDbContext;
        protected DbSet<T> _dbSet;
        public EFBaseRepositoryImpl(DbContext hospitalWeChatPayDBEntities)
        {
            _hospitalWeChatPayDBDbContext = hospitalWeChatPayDBEntities;
            _dbSet = _hospitalWeChatPayDBDbContext.Set<T>();
        }

        /// <summary>
        /// 获取单个
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <returns></returns>
        public T? First(Expression<Func<T, bool>>? expression = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            return _dbSet.FirstOrDefault(expression);
        }

        /// <summary>
        /// 查询数量
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public async Task<int> CountAsync(Expression<Func<T, bool>>? expression = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            return await _dbSet.CountAsync(expression);
        }

        /// <summary>
        /// 查询数量
        /// </summary>
        /// <param name="expression"></param>
        /// <returns></returns>
        public int Count(Expression<Func<T, bool>>? expression = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            return  _dbSet.Count(expression);
        }

        /// <summary>
        /// 获取单个
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <returns></returns>
        public async Task<T?> FirstAsync(Expression<Func<T, bool>>? expression = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            return await _dbSet.FirstOrDefaultAsync(expression);
        }

        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <param name="orderByExpression">排序方式</param>
        /// <param name="orderByEnum">排序方式</param>
        /// <returns></returns>
        public List<T> Find(Expression<Func<T, bool>>? expression = null, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum? orderByEnum = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            orderByExpression ??= m => m.DateAddTime;
            if (orderByEnum == null || orderByEnum == OrderByEnum.Desc)
            {
                queryable = queryable.OrderByDescending(orderByExpression);
            }
            else
            {
                queryable = queryable.OrderBy(orderByExpression);
            }
            return queryable.ToList();
        }

        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <param name="OrderParameter">多条件排序参数</param>
        /// <returns></returns>
        public List<T> Find(Expression<Func<T, bool>>? expression = null, List<(Expression<Func<T, object>>, OrderByEnum)>? OrderParameter = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            if (OrderParameter == null)
            {
                queryable = queryable.OrderByDescending(m => m.DateAddTime);
            }
            else
            {
                foreach (var parameter in OrderParameter)
                {
                    if (parameter.Item1 == null) continue;
                    if (parameter.Item2 == OrderByEnum.Desc)
                    {
                        queryable = queryable.OrderByDescending(parameter.Item1);
                    }
                    else
                    {
                        queryable = queryable.OrderBy(parameter.Item1);
                    }
                }
            }
            return queryable.ToList();
        }

        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <param name="orderByExpression">排序条件</param>
        /// <param name="orderByEnum">排序方式</param>
        /// <returns></returns>
        public async Task<List<T>> FindAsync(Expression<Func<T, bool>>? expression = null, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum? orderByEnum = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            orderByExpression ??= m => m.DateAddTime;
            if (orderByEnum == null || orderByEnum == OrderByEnum.Desc)
            {
                queryable = queryable.OrderByDescending(orderByExpression);
            }
            else
            {
                queryable = queryable.OrderBy(orderByExpression);
            }
            return await queryable.ToListAsync();
        }

        /// <summary>
        /// 列表查询
        /// </summary>
        /// <param name="expression">查询条件</param>
        /// <param name="orderByExpression">排序条件</param>
        /// <param name="orderByEnum">排序方式</param>
        /// <returns></returns>
        public async Task<List<T>> FindAsync(Expression<Func<T, bool>>? expression = null, List<(Expression<Func<T, object>>, OrderByEnum)>? OrderParameter = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            if (OrderParameter == null)
            {
                queryable = queryable.OrderByDescending(m => m.DateAddTime);
            }
            else
            {
                foreach (var parameter in OrderParameter)
                {
                    if (parameter.Item1 == null) continue;
                    if (parameter.Item2 == OrderByEnum.Desc)
                    {
                        queryable = queryable.OrderByDescending(parameter.Item1);
                    }
                    else
                    {
                        queryable = queryable.OrderBy(parameter.Item1);
                    }
                }
            }
            return await queryable.ToListAsync();
        }

        /// <summary>
        /// 列表分页查询
        /// </summary>
        /// <param name="page">分页条件</param>
        /// <param name="expression">查询条件</param>
        /// <param name="orderByExpression">排序条件</param>
        /// <param name="orderByEnum">排序方式</param>
        /// <returns></returns>
        public async Task<(List<T>, PageResultModel)> PageFindAsync(PageModel page, Expression<Func<T, bool>>? expression = null, Expression<Func<T, object>>? orderByExpression = null, OrderByEnum? orderByEnum = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            orderByExpression ??= m => m.DateAddTime;
            if (orderByEnum == null || orderByEnum == OrderByEnum.Desc)
            {
                queryable = queryable.OrderByDescending(orderByExpression);
            }
            else
            {
                queryable = queryable.OrderBy(orderByExpression);
            }
            var dataCount = queryable.Count();
            var pageCount = Math.Ceiling((double)dataCount / page.PageSize);
            queryable = queryable.Skip((page.PageIndex-1)* page.PageSize).Take(page.PageSize);
            return (await queryable.ToListAsync(), new PageResultModel
            {
                PageIndex = page.PageIndex,
                PageSize = page.PageSize,
                TotalPages = (int)pageCount,
                DataCount = dataCount,
            });
        }

        /// <summary>
        /// 列表分页查询
        /// </summary>
        /// <param name="page">分页条件</param>
        /// <param name="expression">查询条件</param>
        /// <param name="orderByExpression">排序条件</param>
        /// <param name="orderByEnum">排序方式</param>
        /// <returns></returns>
        public async Task<(List<T>, PageResultModel)> PageFindAsync(PageModel page, Expression<Func<T, bool>>? expression = null, List<(Expression<Func<T, object>>, OrderByEnum)>? OrderParameter = null)
        {
            if (expression == null)
            {
                expression = m => m.IsDelete == false;
            }
            else
            {

                expression = expression.And(m => m.IsDelete == false);
            }
            var queryable = _dbSet.Where(expression);
            if (OrderParameter == null)
            {
                queryable = queryable.OrderByDescending(m => m.DateAddTime);
            }
            else
            {
                foreach (var parameter in OrderParameter)
                {
                    if (parameter.Item1 == null) continue;
                    if (parameter.Item2 == OrderByEnum.Desc)
                    {
                        queryable = queryable.OrderByDescending(parameter.Item1);
                    }
                    else
                    {
                        queryable = queryable.OrderBy(parameter.Item1);
                    }
                }
            }
            var dataCount = queryable.Count(m => m.IsDelete == false);
            var pageCount = Math.Floor((double)dataCount / page.PageSize);
            queryable = queryable.Skip((page.PageIndex - 1) * page.PageSize).Take(page.PageSize);
            return (await queryable.ToListAsync(), new PageResultModel
            {
                PageIndex = page.PageIndex,
                PageSize = page.PageSize,
                TotalPages = (int)pageCount,
                DataCount = dataCount,
            });
        }
    }
}
